home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
misc
/
amag
/
sh9301b.lha
/
RG-3-D(S.14)
/
rgdemo.mod
< prev
next >
Wrap
Text File
|
1993-01-12
|
16KB
|
420 lines
MODULE RGDemo;
FROM SYSTEM IMPORT ADDRESS,ADR,INLINE,FFP;
FROM Intuition IMPORT NewWindow,IDCMPFlags,IDCMPFlagSet,ScreenPtr,WindowPtr,
WindowFlags,WindowFlagSet,NewScreen,customScreen,
OpenScreen,CloseScreen,OpenWindow,CloseWindow,
ScreenFlags,ScreenFlagSet,IntuiMessagePtr,ScreenToFront;
FROM Graphics IMPORT AllocRaster,TmpRas,AreaInfo,AreaEllipse,AreaMove,Text,
AreaDraw,AreaEnd,BitMap,InitBitMap,ViewModeSet,ViewModes,
FreeRaster,DrawEllipse,SetRast,Move,InitArea,InitTmpRas,
LoadRGB4,SetAPen,InitRastPort,RastPort,RastPortPtr,Draw;
FROM GfxMacros IMPORT SetWrMsk,SetOPen;
FROM Exec IMPORT GetMsg,ReplyMsg;
FROM InOut IMPORT WriteString,WriteLn;
FROM Arts IMPORT TermProcedure;
FROM RandomNumber IMPORT RND,PutSeed;
FROM MathLibFFP IMPORT sin,cos,pi;
CONST rotsteps = 360; (* Anzahl der Rot.schritte der Würfelanimation *)
p = 0.2; (* Perspekt. Verkürzungsfaktor *)
alfa = -70.0*pi/180.0; (* Winkel, unter dem die Rotations-
ebene der Würfelanim. gesehen wird *)
dphi = pi/180.0; (* Rotationswinkel-Inkrement *)
XShift = 320; (* Offset, um die Animation in die Bildschirm- *)
YShift = 128; (* mitte zu rücken *)
ZFocus = 1000.0; (* z-Koord. d. Fluchtpunktes (0|0|ZFocus) *)
TYPE Ecken = ARRAY[1..8],[1..3] OF FFP;
FlaechenIndex = ARRAY[1..6] OF INTEGER;
ZvonFCenter = ARRAY[1..6] OF FFP;
VAR RGWindow : NewWindow;
RGScreen : NewScreen;
RGWindowPtr0 : WindowPtr;
RGScreenPtr0 : ScreenPtr;
RGWindowPtr1 : WindowPtr;
RGScreenPtr1 : ScreenPtr;
RGWinRPPtr0 : RastPortPtr;
RGWinRPPtr1 : RastPortPtr;
RGRPPtr : RastPortPtr;
Buffer : ARRAY[0..49] OF CARDINAL;
AreaMemPtr : ADDRESS;
RGDemoTmpRas : TmpRas;
RGDemoAreaInfo : AreaInfo;
IntuiMsg,IntuiMsg1 : IntuiMessagePtr;
ok,EX,ausserhalb : BOOLEAN;
class : IDCMPFlagSet;
WP1org : Ecken; (* Ecken d. 1.Würfels original *)
WP1 : Ecken; (* transformiert *)
WP2org : Ecken; (* 2. original *)
WP2 : Ecken; (* transformiert *)
F : ARRAY[1..6],[1..5] OF INTEGER; (* Würf.flächn *)
FIndexW1 : FlaechenIndex; (* Numerierung der Flächen *)
FIndexW2 : FlaechenIndex;
ZFCW1 : ZvonFCenter; (* z-Koordinaten der Würf.flächn *)
ZFCW2 : ZvonFCenter;
Trafo : ARRAY[1..3],[1..3] OF FFP; (* Rot. matrix *)
ARInt : ARRAY[1..108*rotsteps] OF INTEGER; (* Animat.*)
I1 : LONGINT; (* Index für ARInt *)
RGDelta : FFP; (* Faktor für Rot/Grün-Versatz *)
PROCEDURE CloseDown ; (* räumt zum Schluß alles auf *)
VAR i,j : INTEGER;
BEGIN (* CloseDown *)
IF RGWindowPtr0 # NIL THEN CloseWindow(RGWindowPtr0); END;
IF RGScreenPtr0 # NIL THEN CloseScreen(RGScreenPtr0); END;
IF RGWindowPtr1 # NIL THEN CloseWindow(RGWindowPtr1); END;
IF RGScreenPtr1 # NIL THEN CloseScreen(RGScreenPtr1); END;
IF AreaMemPtr # NIL THEN FreeRaster(AreaMemPtr,640,256); END;
END CloseDown ;
PROCEDURE Okay(text : ARRAY OF CHAR ; adr : ADDRESS):BOOLEAN ;
BEGIN (* Okay *)
IF adr = NIL THEN
WriteString(text);WriteString(" läßt sich nicht oeffnen !!") ; WriteLn ;
WriteString(" ProgrammABBRUCH") ; WriteLn ; RETURN(FALSE);
ELSE RETURN(TRUE); END (* IF *) ;
END Okay ;
PROCEDURE InitOberfl; (* initialisiert 2 Screens etc. für DoubleBuffering *)
VAR i,j :INTEGER;
BEGIN
RGScreenPtr0:=NIL; RGWindowPtr0:=NIL;
RGScreenPtr1:=NIL; RGWindowPtr1:=NIL; AreaMemPtr:=NIL;
WITH RGScreen DO
leftEdge := 0 ; topEdge := 0 ; width := 640 ; height := 256 ; depth := 4 ;
detailPen := 0 ; blockPen := 1 ; viewModes := ViewModeSet{hires} ;
type := customScreen; font := NIL ; defaultTitle :=ADR("NIL");
gadgets := NIL ; customBitMap := NIL;
END (* WITH *) ;
RGScreenPtr0 := OpenScreen(RGScreen) ;
IF NOT Okay("RGScreen",RGScreenPtr0) THEN CloseDown;HALT;END;
WITH RGWindow DO
leftEdge:=0; topEdge:=1; width:=640; height:=255;
detailPen:=9; blockPen:=15; idcmpFlags:=IDCMPFlagSet{closeWindow};
flags:=WindowFlagSet{windowClose,gimmeZeroZero,activate};
firstGadget:=NIL; checkMark:=NIL; title:=ADR("Rot-Grün-3D-Demo 0");
bitMap:=NIL; type:=customScreen; screen:= RGScreenPtr0; minWidth:=600;
maxWidth:=640; minHeight:=256; maxHeight:=256;
END;
RGWindowPtr0:=OpenWindow(RGWindow);
IF NOT Okay("RGWindow",RGWindowPtr0) THEN CloseDown;HALT;END;
RGWinRPPtr0:=RGWindowPtr0^.rPort;
RGScreenPtr1 := OpenScreen(RGScreen) ;
IF NOT Okay("RGScreen",RGScreenPtr1) THEN CloseDown;HALT;END;
WITH RGWindow DO
title:=ADR("Rot-Grün-3D-Demo 1"); screen:= RGScreenPtr1;
END;
RGWindowPtr1:=OpenWindow(RGWindow);
IF NOT Okay("RGWindow",RGWindowPtr1) THEN CloseDown;HALT;END;
RGWinRPPtr1:=RGWindowPtr1^.rPort;
RGRPPtr:=RGWinRPPtr0;
AreaMemPtr:=AllocRaster(640,256);
IF NOT Okay("AreaMem",AreaMemPtr) THEN CloseDown; HALT;END;
FOR i:=0 TO 49 DO Buffer[i]:=0;END;
InitArea(RGDemoAreaInfo,ADR(Buffer),20); (* AreaInfo initialisieren *)
InitTmpRas(RGDemoTmpRas,AreaMemPtr,20480); (* TmpRas initialisieren *)
RGWinRPPtr0^.tmpRas:=ADR(RGDemoTmpRas); (* TmpRas übergeben *)
RGWinRPPtr0^.areaInfo:=ADR(RGDemoAreaInfo);(* AreaInfo übergeben *)
RGWinRPPtr1^.tmpRas:=ADR(RGDemoTmpRas); (* TmpRas übergeben *)
RGWinRPPtr1^.areaInfo:=ADR(RGDemoAreaInfo);(* AreaInfo übergeben *)
PutSeed(2);
END InitOberfl;
PROCEDURE FarbTabelle;(* $E- *)
BEGIN
INLINE(0007H,0057H,0077H,0097H,
0507H,0557H,0577H,0597H,
0707H,0757H,0777H,0797H,
0907H,0957H,0977H,0997H);
END FarbTabelle;
PROCEDURE FarbTabelleLaden;
BEGIN
LoadRGB4(ADR(RGWindowPtr0^.wScreen^.viewPort),ADR(FarbTabelle),16);
LoadRGB4(ADR(RGWindowPtr1^.wScreen^.viewPort),ADR(FarbTabelle),16)
END FarbTabelleLaden;
PROCEDURE ScheibenZeichnen;
VAR i,k,r,x,y,deltarot,deltagruen,max : INTEGER;
Pen : CARDINAL;
BEGIN
max:=20;
FOR i:=1 TO 2*max DO
ausserhalb:=TRUE;
WHILE ausserhalb DO
x:=1+RND(640);y:=1+RND(256);
IF i<max THEN deltarot:=max-i;deltagruen:=0;k:=max-i;r:=20+i DIV 2;
ELSE deltarot:=0;deltagruen:=i-max;k:=i-max;r:=20+i DIV 2;
END;
IF (2+2*r+k<x) AND (638-2*r>x)
AND (2+r <y) AND (240-r >y) THEN
ausserhalb:=FALSE;
END;
END;
Pen:=5*CARDINAL(RND(3)+1);
FOR k:=0 TO 49 DO Buffer[k]:=0;END;
(* rote Ansicht zeichnen *)
SetAPen(RGWinRPPtr1,Pen); SetWrMsk(RGWinRPPtr1,0F3H);
ok:=AreaEllipse(RGWinRPPtr1,x-deltarot,y,2*r,r);
ok:=AreaEnd(RGWinRPPtr1);
SetAPen(RGWinRPPtr1,0);
DrawEllipse(RGWinRPPtr1,x-deltarot,y,2*r,r);
(* grüne Ansicht zeichnen *)
SetAPen(RGWinRPPtr1,Pen);SetWrMsk(RGWinRPPtr1,0FCH);
FOR k:=0 TO 49 DO Buffer[k]:=0;END;
ok:=AreaEllipse(RGWinRPPtr1,x-deltagruen,y,2*r,r);
ok:=AreaEnd(RGWinRPPtr1);
SetAPen(RGWinRPPtr1,0);
DrawEllipse(RGWinRPPtr1,x-deltagruen,y,2*r,r)
END;
SetWrMsk(RGWinRPPtr1,0FFH);SetAPen(RGWinRPPtr1,15);
Move(RGWinRPPtr1,20,10);Text(RGWinRPPtr1,ADR
("AMIGA berechnet jetzt die Würfelanimation, bitte ca. 2 min. warten..."),69);
END ScheibenZeichnen;
PROCEDURE AnimWuerfel;
VAR i,j,k,n : INTEGER;
m : LONGINT;
PROCEDURE QuickSort(l,r:CARDINAL;VAR Wt:ZvonFCenter;VAR FI:FlaechenIndex);
(* sortiert für die Hiddenline Darstellung die Flächen nach der z-Koordinate
des Flächenzentrums *)
VAR i,j : CARDINAL;
Ind : INTEGER;
x,y : FFP;
BEGIN
i:=l;j:=r; x:=Wt[(l+r) DIV 2];
REPEAT
WHILE Wt[i]<x DO INC(i) END; WHILE x<Wt[j] DO DEC(j) END;
IF i<=j THEN
y:=Wt[i]; Ind:=FI[i];
Wt[i]:=Wt[j]; FI[i]:=FI[j];
Wt[j]:=y; FI[j]:=Ind;
INC(i); DEC(j);
END;
UNTIL i>j;
IF l<j THEN QuickSort(l,j,Wt,FI) END;
IF l<r THEN QuickSort(i,r,Wt,FI) END;
END QuickSort;
PROCEDURE RechneARInt(VAR WP:Ecken;VAR P1,P2,P3,P4,Pen:INTEGER);
(* Berechnet die Animationssequenz im voraus und speichert alles in ARInt *)
VAR j :INTEGER;
BEGIN
ARInt[I1]:=Pen;INC(I1);
ARInt[I1]:=INTEGER(WP[P1][1]*(ZFocus-WP[P1][3])/ZFocus
+RGDelta*WP[P1][3]+0.5)+XShift; INC(I1);
ARInt[I1]:=INTEGER(WP[P1][2]*(ZFocus-WP[P1][3])/ZFocus) DIV 2 +YShift;INC(I1);
ARInt[I1]:=INTEGER(WP[P2][1]*(ZFocus-WP[P2][3])/ZFocus
+RGDelta*WP[P2][3]+0.5)+XShift; INC(I1);
ARInt[I1]:=INTEGER(WP[P2][2]*(ZFocus-WP[P2][3])/ZFocus) DIV 2 +YShift;INC(I1);
ARInt[I1]:=INTEGER(WP[P3][1]*(ZFocus-WP[P3][3])/ZFocus
+RGDelta*WP[P3][3]+0.5)+XShift; INC(I1);
ARInt[I1]:=INTEGER(WP[P3][2]*(ZFocus-WP[P3][3])/ZFocus) DIV 2 +YShift;INC(I1);
ARInt[I1]:=INTEGER(WP[P4][1]*(ZFocus-WP[P4][3])/ZFocus
+RGDelta*WP[P4][3]+0.5)+XShift; INC(I1);
ARInt[I1]:=INTEGER(WP[P4][2]*(ZFocus-WP[P4][3])/ZFocus) DIV 2 +YShift;
IF I1<108*rotsteps THEN INC(I1)
ELSE I1:=1
END;
END RechneARInt;
BEGIN
I1:=1; RGDelta:=0.04;
(* Definition der Würfelflächen anhand der aufspannenden Ecken *)
F[1][1]:=1; F[1][2]:=2; F[1][3]:=3; F[1][4]:=4; F[1][5]:=5;
F[2][1]:=1; F[2][2]:=2; F[2][3]:=6; F[2][4]:=5; F[2][5]:=5;
F[3][1]:=2; F[3][2]:=3; F[3][3]:=7; F[3][4]:=6; F[3][5]:=10;
F[4][1]:=1; F[4][2]:=4; F[4][3]:=8; F[4][4]:=5; F[4][5]:=5;
F[5][1]:=3; F[5][2]:=4; F[5][3]:=8; F[5][4]:=7; F[5][5]:=5;
F[6][1]:=5; F[6][2]:=6; F[6][3]:=7; F[6][4]:=8; F[6][5]:=10;
(* Koordinaten der Würfelecken im KO-System 2;
KO-System 1: Ursprung: linke obere Bildschirmecke;
x-Achse: oberer Bildschirmrand links -> rechts;
y-Achse: linker Bildschirmrand oben -> unten;
z-Achse: in Blickrichtung in den Bildschirm hinein
KO-System 2: geht aus KO-System 1 durch Drehung um alfa um die x-Achse hervor *)
WP1org[1,1]:=-1.5; WP1org[1,2]:= 1.0; WP1org[1,3]:=-1.0;
WP1org[2,1]:=-3.5; WP1org[2,2]:= 1.0; WP1org[2,3]:=-1.0;
WP1org[3,1]:=-3.5; WP1org[3,2]:=-1.0; WP1org[3,3]:=-1.0;
WP1org[4,1]:=-1.5; WP1org[4,2]:=-1.0; WP1org[4,3]:=-1.0;
WP1org[5,1]:=-1.5; WP1org[5,2]:= 1.0; WP1org[5,3]:= 1.0;
WP1org[6,1]:=-3.5; WP1org[6,2]:= 1.0; WP1org[6,3]:= 1.0;
WP1org[7,1]:=-3.5; WP1org[7,2]:=-1.0; WP1org[7,3]:= 1.0;
WP1org[8,1]:=-1.5; WP1org[8,2]:=-1.0; WP1org[8,3]:= 1.0;
FOR i:=1 TO 8 DO
WP2org[i][1]:=WP1org[i][1]+5.0;
WP2org[i][2]:=WP1org[i][2]; WP2org[i][3]:=WP1org[i][3];
END;
(* Vergrößerungsfaktor anbringen *)
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO
WP1org[i,j]:=WP1org[i,j]*45.0; WP2org[i,j]:=WP2org[i,j]*45.0;
END; END;
(* Koordinaten in KO-System 1 umrechnen *)
Trafo[1,1]:= 1.0; Trafo[1,2]:= 0.0; Trafo[1,3]:= 0.0;
Trafo[2,1]:= 0.0; Trafo[2,2]:= cos(alfa); Trafo[2,3]:=-sin(alfa);
Trafo[3,1]:= 0.0; Trafo[3,2]:= sin(alfa); Trafo[3,3]:= cos(alfa);
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO
WP1[i,j]:=0.0; WP2[i,j]:=0.0;
END; END;
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO FOR k:=1 TO 3 DO
WP1[i,j]:=WP1[i,j]+Trafo[j,k]*WP1org[i,k];
WP2[i,j]:=WP2[i,j]+Trafo[j,k]*WP2org[i,k];
END; END; END;
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO
WP1org[i,j]:=WP1[i,j]; WP2org[i,j]:=WP2[i,j];
END; END;
(* Matrix für die Rotation der Würfel um dphi um die z-Achse von KO-System 2 *)
Trafo[1,1]:= cos(dphi);
Trafo[1,2]:= cos(alfa)*sin(dphi);
Trafo[1,3]:= sin(dphi)*sin(alfa);
Trafo[2,1]:= -cos(alfa)*sin(dphi);
Trafo[2,2]:= cos(alfa)*cos(alfa)*cos(dphi)+sin(alfa)*sin(alfa);
Trafo[2,3]:= cos(alfa)*cos(dphi)*sin(alfa)-sin(alfa)*cos(alfa);
Trafo[3,1]:=-sin(alfa)*sin(dphi);
Trafo[3,2]:= sin(alfa)*cos(alfa)*cos(dphi)-cos(alfa)*sin(alfa);
Trafo[3,3]:= sin(alfa)*sin(alfa)*cos(dphi)+cos(alfa)*cos(alfa);
FOR m:=1 TO rotsteps DO
(* neue Koordinaten nach der Rotation um dphi berechnen *)
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO
WP1[i,j]:=0.0; WP2[i,j]:=0.0;
END; END;
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO FOR k:=1 TO 3 DO
WP1[i,j]:=WP1[i,j]+Trafo[j,k]*WP1org[i,k];
WP2[i,j]:=WP2[i,j]+Trafo[j,k]*WP2org[i,k];
END; END; END;
FOR i:=1 TO 8 DO FOR j:=1 TO 3 DO
WP1org[i,j]:=WP1[i,j]; WP2org[i,j]:=WP2[i,j];
END; END;
(* Abstand der Flächenzentren vom Betrachter berechnen *)
FOR i:=1 TO 6 DO
j:=F[i,1]; k:=F[i,3];
ZFCW1[i]:=(WP1[j,1]+WP1[k,1])*(WP1[j,1]+WP1[k,1])+
(WP1[j,2]+WP1[k,2])*(WP1[j,2]+WP1[k,2])+
(WP1[j,3]+WP1[k,3]+50.0*ZFocus)*
(WP1[j,3]+WP1[k,3]+50.0*ZFocus);
ZFCW2[i]:=(WP2[j,1]+WP2[k,1])*(WP2[j,1]+WP2[k,1])+
(WP2[j,2]+WP2[k,2])*(WP2[j,2]+WP2[k,2])+
(WP2[j,3]+WP2[k,3]+50.0*ZFocus)*
(WP2[j,3]+WP2[k,3]+50.0*ZFocus);
END;
FOR i:=1 TO 6 DO FIndexW1[i]:=i; FIndexW2[i]:=i; END;
(* Flächen für Hiddenline-Darstellung sortieren *)
QuickSort(1,6,ZFCW1,FIndexW1); QuickSort(1,6,ZFCW2,FIndexW2);
n:=1;
RGDelta:=-RGDelta;
(* für beide Würfel die sichtbaren drei Flächen im Anim-speicher ablegen *)
LOOP
IF ZFCW2[1]<ZFCW1[1] THEN
FOR i:=3 TO 1 BY -1 DO
j:=FIndexW1[i];
RechneARInt(WP1org,F[j,1],F[j,2],F[j,3],F[j,4],F[j,5]);
END;
FOR i:=3 TO 1 BY -1 DO
j:=FIndexW2[i];
RechneARInt(WP2org,F[j,1],F[j,2],F[j,3],F[j,4],F[j,5]);
END;
ELSE
FOR i:=3 TO 1 BY -1 DO
j:=FIndexW2[i];
RechneARInt(WP2org,F[j,1],F[j,2],F[j,3],F[j,4],F[j,5]);
END;
FOR i:=3 TO 1 BY -1 DO
j:=FIndexW1[i];
RechneARInt(WP1org,F[j,1],F[j,2],F[j,3],F[j,4],F[j,5]);
END;
END;
IF n=2 THEN
EXIT
ELSE
INC(n); RGDelta:=-RGDelta;
END;
END;
END;
n:=1;
SetWrMsk(RGRPPtr,0FFH); SetRast(RGRPPtr,0);
m:=-8;
(* Animation zeichnen *)
LOOP
INC(m,9);
IF m+8>108*rotsteps THEN m:=1 END;
IF (n=1) THEN SetWrMsk(RGRPPtr,0F3H);SetOPen(RGRPPtr,10); END;
IF (n=7) THEN SetWrMsk(RGRPPtr,0FCH);SetOPen(RGRPPtr,10); END;
FOR j:=0 TO 49 DO Buffer[j]:=0;END;
SetAPen(RGRPPtr,ARInt[m]);
ok:=AreaMove(RGRPPtr,ARInt[m+1],ARInt[m+2]);
ok:=AreaDraw(RGRPPtr,ARInt[m+3],ARInt[m+4]);
ok:=AreaDraw(RGRPPtr,ARInt[m+5],ARInt[m+6]);
ok:=AreaDraw(RGRPPtr,ARInt[m+7],ARInt[m+8]);
ok:=AreaEnd(RGRPPtr);
IF (n=12) THEN
n:=0;
IF (RGRPPtr=RGWinRPPtr1) THEN
RGRPPtr:=RGWinRPPtr0;ScreenToFront(RGScreenPtr1);
ELSE
RGRPPtr:=RGWinRPPtr1;ScreenToFront(RGScreenPtr0);
END;
SetWrMsk(RGRPPtr,0FFH); SetRast(RGRPPtr,0);
END;
INC(n);
EX:=FALSE;
IF (RGWindowPtr0 # NIL) THEN
IntuiMsg:=GetMsg(RGWindowPtr0^.userPort);
WHILE IntuiMsg#NIL DO
class:=IntuiMsg^.class; ReplyMsg(IntuiMsg);
IF (closeWindow IN class) THEN EX:=TRUE;END;
IntuiMsg:=GetMsg(RGWindowPtr0^.userPort);
END;
END;
IF (RGWindowPtr1 # NIL) THEN
IntuiMsg:=GetMsg(RGWindowPtr1^.userPort);
WHILE IntuiMsg#NIL DO
class:=IntuiMsg^.class; ReplyMsg(IntuiMsg);
IF (closeWindow IN class) THEN EX:=TRUE;END;
IntuiMsg:=GetMsg(RGWindowPtr1^.userPort);
END;
END;
IF EX THEN EXIT;END;
END;
END AnimWuerfel;
BEGIN
WriteString("Rot-Grün-3D-Demo Version 1.0,");WriteLn;
WriteString("Copyright: Bernfried Brüggemann, Munich 22.04.92");WriteLn;
TermProcedure(CloseDown);
InitOberfl;
FarbTabelleLaden;
ScheibenZeichnen;
AnimWuerfel;
END RGDemo.